﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;

namespace DungeonAndDragonApplication.Controller.Network.Client
{
    public class Client
    {
        private Dictionary<int, Socket> listOfSockets;
        private TcpClient socket;
        private StringBuilder sbSentMessages;
        private string stringInput = string.Empty;

        private Thread sendThread;
        private Thread receiveThread;

        private int BUFFER_SIZE = 1024;
        private int SLEEP_TIME_MILLISECOND = 500;
        private ControllerManager cm;


        public Client(ControllerManager controllerManager)
        {
            socket = new TcpClient();
            sbSentMessages = new StringBuilder();
            stringInput = string.Empty;
            cm = controllerManager;
        }

        public void ConnectToServer()
        {

        }

        public void ConnectToServer(string ipAddress, int port)
        {
            socket.Connect(ipAddress, port);

            sendThread = new Thread(new ParameterizedThreadStart(SendToServer));
            sendThread.Start(socket.GetStream());

            receiveThread = new Thread(new ParameterizedThreadStart(ReceivedFromServer));
            receiveThread.Start(socket.GetStream());
        }

        private void ReceivedFromServer(object param)
        {
            NetworkStream ns = (NetworkStream)param;
            bool flag = false;
            byte[] buffer = new byte[BUFFER_SIZE];
            object state = null;
            AsyncCallback callback = new AsyncCallback(readFromClient);

            while (true)
            {
                lock (ns)
                {
                    while (ns.DataAvailable)
                    {
                        ns.BeginRead(buffer, 0, BUFFER_SIZE, callback, state);
                        flag = true;
                    }
                }
                if (flag)
                {
                    flag = false;
                    string s = string.Empty;
                    //DATA IS AVAILABLE
                    //for (int i = 0; i < buffer.Length; i++)
                    //{
                    //    s += (char)buffer[i];
                    //}

                    string message = ByteToStringConverter(buffer);

                    System.Diagnostics.Debug.WriteLine("Answer from server:" + message + Environment.NewLine);

                    lock (cm)
                    {
                        cm.ReceiveMessage("\n Answer from server: " + message + Environment.NewLine);
                    }
                }

                //Sleep the process for a little while
                Thread.Sleep(SLEEP_TIME_MILLISECOND);
            }
        }


        private string ByteToStringConverter(byte[] buffer)
        {
            return Encoding.UTF8.GetString(buffer, 0, buffer.Length).Replace("\0", string.Empty);
        }

        private void SendToServer(object param)
        {
            NetworkStream serverStream = (NetworkStream)param;

            while (!stringInput.ToLower().Contains("quit"))
            {
                if (stringInput == string.Empty || stringInput == null)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                    continue;
                }

                byte[] outStream = System.Text.Encoding.ASCII.GetBytes(stringInput);

                stringInput = string.Empty;

                lock (serverStream)
                {
                    serverStream.Write(outStream, 0, outStream.Length);
                    serverStream.Flush();
                }
            }

            serverStream.Close();
        }

        public string StringInput
        {
            set { stringInput = value; }
        }

        static void readFromClient(IAsyncResult results)
        {
            //METHOD WAS CALLED BY THE DELEGATE
        }
    }
}
